2D Visualization笔记(X3) DynamicDataDisplay(wpf)(二)

Hello World Demo 分析
LineGraph的UpdateCore中有GetTransform和transform.DataToScreen(points). GetTransform是在父类PointsGraphBase中定义的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private DataTransform dataTransform = null;
public DataTransform DataTransform
{
get { return dataTransform; }
set
{
if (dataTransform != value)
{
dataTransform = value;
Update();
}
}
}

protected CoordinateTransform GetTransform()
{
if (Plotter == null)
return null;

var transform = Plotter2D.Viewport.Transform;
if (dataTransform != null)
transform = transform.WithDataTransform(dataTransform);

return transform;
}

一个窗口中可以有多个Plot, 一个Plot就是一个视口(viewPort);CoordinateTransform有2个变换组成, 一个是数据变换(dataTransform), 先将数据变换到Plot(即视口viewPort), 另一个是视口变换, 将Plot变换到窗口的某一位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
	/// <summary>
/// Base class for all data transforms.
/// Defines methods to transform point from data coordinate system to viewport coordinates and vice versa.
/// </summary>
public abstract class DataTransform
{
/// <summary>
/// Transforms the point in data coordinates to viewport coordinates.
/// </summary>
/// <param name="pt">The point in data coordinates.</param>
/// <returns></returns>
public abstract Point DataToViewport(Point pt);
/// <summary>
/// Transforms the point in viewport coordinates to data coordinates.
/// </summary>
/// <param name="pt">The point in viewport coordinates.</param>
/// <returns></returns>
public abstract Point ViewportToData(Point pt);

private static readonly DataRect defaultDomain = DataRect.Empty;
/// <summary>
/// Gets the data domain.
/// </summary>
/// <value>The data domain.</value>
public virtual DataRect DataDomain { get { return defaultDomain; } }
}


namespace Microsoft.Research.DynamicDataDisplay
{
/// <summary>
/// A central class in 2d coordinate transformation in DynamicDataDisplay.
/// Provides methods to transform point from one coordinate system to another.
/// </summary>
public sealed class CoordinateTransform
{
private CoordinateTransform(Rect visibleRect, Rect screenRect)
{
this.visibleRect = visibleRect;
this.screenRect = screenRect;

rxToScreen = screenRect.Width / visibleRect.Width;
ryToScreen = screenRect.Height / visibleRect.Height;
cxToScreen = visibleRect.Left * rxToScreen - screenRect.Left;
cyToScreen = screenRect.Height + screenRect.Top + visibleRect.Top * ryToScreen;

rxToData = visibleRect.Width / screenRect.Width;
ryToData = visibleRect.Height / screenRect.Height;
cxToData = screenRect.Left * rxToData - visibleRect.Left;
cyToData = visibleRect.Height + visibleRect.Top + screenRect.Top * ryToData;
}

#region Coeffs
double rxToScreen;
double ryToScreen;
double cxToScreen;
double cyToScreen;

double rxToData;
double ryToData;
double cxToData;
double cyToData;
#endregion

#region Creation methods

internal CoordinateTransform WithRects(Rect visibleRect, Rect screenRect)
{
CoordinateTransform copy = new CoordinateTransform(visibleRect, screenRect);
copy.dataTransform = dataTransform;
return copy;
}

/// <summary>
/// Creates a new instance of CoordinateTransform with the given data transform.
/// </summary>
/// <param name="dataTransform">The data transform.</param>
/// <returns></returns>
public CoordinateTransform WithDataTransform(DataTransform dataTransform)
{
if (dataTransform == null)
throw new ArgumentNullException("dataTransform");

CoordinateTransform copy = new CoordinateTransform(visibleRect, screenRect);
copy.dataTransform = dataTransform;
return copy;
}

internal static CoordinateTransform CreateDefault()
{
CoordinateTransform transform = new CoordinateTransform(new Rect(0, 0, 1, 1), new Rect(0, 0, 1, 1));

return transform;
}

#endregion

#region Transform methods

/// <summary>
/// Transforms point from data coordinates to screen.
/// </summary>
/// <param name="dataPoint">The point in data coordinates.</param>
/// <returns></returns>
public Point DataToScreen(Point dataPoint)
{
Point viewportPoint = dataTransform.DataToViewport(dataPoint);

Point screenPoint = new Point(viewportPoint.X * rxToScreen - cxToScreen,
cyToScreen - viewportPoint.Y * ryToScreen);

return screenPoint;
}

/// <summary>
/// Transforms point from screen coordinates to data coordinates.
/// </summary>
/// <param name="screenPoint">The point in screen coordinates.</param>
/// <returns></returns>
public Point ScreenToData(Point screenPoint)
{
Point viewportPoint = new Point(screenPoint.X * rxToData - cxToData,
cyToData - screenPoint.Y * ryToData);

Point dataPoint = dataTransform.ViewportToData(viewportPoint);

return dataPoint;
}

/// <summary>
/// Transforms point from viewport coordinates to screen coordinates.
/// </summary>
/// <param name="viewportPoint">The point in viewport coordinates.</param>
/// <returns></returns>
public Point ViewportToScreen(Point viewportPoint)
{
Point screenPoint = new Point(viewportPoint.X * rxToScreen - cxToScreen,
cyToScreen - viewportPoint.Y * ryToScreen);

return screenPoint;
}

/// <summary>
/// Transforms point from screen coordinates to viewport coordinates.
/// </summary>
/// <param name="screenPoint">The point in screen coordinates.</param>
/// <returns></returns>
public Point ScreenToViewport(Point screenPoint)
{
Point viewportPoint = new Point(screenPoint.X * rxToData - cxToData,
cyToData - screenPoint.Y * ryToData);

return viewportPoint;
}

#endregion

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Rect visibleRect;
/// <summary>
/// Gets the viewport rectangle.
/// </summary>
/// <value>The viewport rect.</value>
public Rect ViewportRect
{
get { return visibleRect; }
}

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Rect screenRect;
/// <summary>
/// Gets the screen rectangle.
/// </summary>
/// <value>The screen rect.</value>
public Rect ScreenRect
{
get { return screenRect; }
}

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private DataTransform dataTransform = DataTransforms.Identity;
/// <summary>
/// Gets the data transform.
/// </summary>
/// <value>The data transform.</value>
public DataTransform DataTransform
{
get { return dataTransform; }
}
}
}

visibleRect是Plot所在的Rect, screenRect是窗口所在的Rect, 默认两个是重合的

1
2
3
4
5
6
internal static CoordinateTransform CreateDefault()
{
CoordinateTransform transform = new CoordinateTransform(new Rect(0, 0, 1, 1), new Rect(0, 0, 1, 1));

return transform;
}